use serde::{Deserialize, Serialize};
use tokio::sync::{Mutex, OnceCell};

#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct SnmpConfig {
    #[serde(default = "default_version")]
    pub version: String,
    pub community: String,
    pub host: String,

    #[serde(default = "get_default_oid_list")]
    pub oid_list: Vec<String>,
    pub frequency: u64,
    pub collect_type: String,

    #[serde(default = "default_trap_community")]
    pub trap_community: String,
    #[serde(default = "default_trap_port")]
    pub trap_port: u16,
}

static SNMP: OnceCell<Mutex<SnmpConfig>> = OnceCell::const_new();

pub async fn get_snmp() -> &'static Mutex<SnmpConfig> {
    SNMP.get_or_init(|| async { Mutex::new(SnmpConfig::default()) })
        .await
}

pub async fn update_snmp_global(snmp: SnmpConfig) {
    *get_snmp().await.lock().await = snmp;
}

fn default_version() -> String {
    "2c".to_owned()
}

fn default_trap_community() -> String {
    "public".to_owned()
}

fn default_trap_port() -> u16 {
    162
}

/// 企业OID 大全 https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers
/// 目前支持解析企业OID
/// ```text
/// cisco: .1.3.6.1.4.1.9
/// huawei: .1.3.6.1.4.1.2011
/// hillstone: .1.3.6.1.4.1.28557
/// ```
fn get_default_oid_list() -> Vec<String> {
    vec![
        ".1.3.6.1.2.1.31.1.1.1.1",
        ".1.3.6.1.2.1.4.20.1.2",
        ".1.3.6.1.2.1.2.2.1.6",
        ".1.3.6.1.2.1.31.1.1.1.15",
        ".1.3.6.1.2.1.2.2.1.4",
        ".1.3.6.1.2.1.2.2.1.2",
        ".1.3.6.1.2.1.31.1.1.1.6",
        ".1.3.6.1.2.1.2.2.1.16",
        ".1.3.6.1.2.1.2.2.1.10",
        ".1.3.6.1.2.1.2.2.1.14",
        ".1.3.6.1.2.1.2.2.1.20",
        ".1.3.6.1.2.1.31.1.1.1.10",
        ".1.3.6.1.2.1.4.24.4.1.8",
        ".1.3.6.1.2.1.1.1.0",
        ".1.3.6.1.2.1.1.2.0",
        ".1.3.6.1.2.1.1.3.0",
        ".1.3.6.1.2.1.1.5.0",
        ".1.3.6.1.2.1.5.24.0",
        ".1.3.6.1.2.1.2.1.0",
        ".1.3.6.1.2.1.31.1.1.1.17",
        ".1.3.6.1.2.1.4.2.0",
        ".1.3.6.1.2.1.1.7.0",
        ".1.3.6.1.2.1.4.13.0",
        ".1.3.6.1.2.1.2.2.1.8",
        ".1.3.6.1.4.1.28557.2.2.1.1.0",
        ".1.3.6.1.4.1.28557.2.2.1.2.0",
        ".1.3.6.1.4.1.9.9.109.1.1.1.1",
        ".1.3.6.1.4.1.9.9.48.1.1.1",
        ".1.3.6.1.4.1.28557.2.2.1.3",
        ".1.3.6.1.4.1.28557.2.2.1.4",
        ".1.3.6.1.4.1.28557.2.2.1.5",
        ".1.3.6.1.4.1.28557.2.2.1.6",
        ".1.3.6.1.4.1.28557.2.2.1.7",
        ".1.3.6.1.4.1.2011.6.122.15.1.2.1.1",
        ".1.3.6.1.4.1.2011.6.122.15.1.2.1.4",
        ".1.3.6.1.4.1.2011.5.25.31.1.1.1.1",
        ".1.3.6.1.4.1.2011.6.122.15.5.3.1",
    ]
    .into_iter()
    .map(|x| x.to_owned())
    .collect()
}
